package com.xbjtech.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.excel.poi.util.PoiAnalyticalData;
import com.excel.poi.util.PoiUtil;
import com.github.pagehelper.PageInfo;
import com.xbjtech.model.Hxm;
import com.xbjtech.model.Order;
import com.xbjtech.model.OrderExample;
import com.xbjtech.model.OrderExample.Criteria;
import com.xbjtech.model.Region;
import com.xbjtech.model.Seller;
import com.xbjtech.model.User;
import com.xbjtech.service.HxmRandomService;
import com.xbjtech.service.OrderService;
import com.xbjtech.service.RegionService;
import com.xbjtech.service.SellerService;
import com.xbjtech.service.StoreService;
import com.xbjtech.vo.OrderExcelInputModel;
import com.xbjtech.vo.OrderExcelOutModel;
import com.xbjtech.vo.OrderVO;

import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/order")
@Slf4j
public class OrderController {
	
	@Autowired
	OrderService orderService;
	
	@Autowired
	SellerService sellerService;
	
	@Autowired
	RegionService regionService;
	
	@Autowired
	StoreService storeService;
	
	@Autowired
	HxmRandomService hxmRandomService;
	
//	@RequiresRoles({"admin", "user"}) 自己去试
	@GetMapping("/list")
	public String list(Model model) {
		List<Seller> sellers = sellerService.getAllSeller();
		model.addAttribute("sellers", sellers);
		return "order/list";
	}
	
	@GetMapping("/edit/{id}")
	public String edit(@PathVariable("id") Long id, Model model) {
		Order order = orderService.getOrderById(id);
		model.addAttribute("order", order);
		List<Seller> sellers = sellerService.getAllSeller();
		model.addAttribute("sellers", sellers);
		return "order/input";
	}
	
	@GetMapping("/view/{id}")
	public String view(@PathVariable("id") Long id, Model model) {
		Order order = orderService.getOrderById(id);
		model.addAttribute("order", order);
		return "order/view";
	}
	
	@GetMapping("/delete/{id}")
	public String delete(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
		try {
			orderService.deleteOrderById(id);
			redirectAttributes.addFlashAttribute("successMessage", "删除成功");
		} catch (Exception e) {
			log.info("OrderController.delete()---->{}", e);
			redirectAttributes.addFlashAttribute("errorMessage", "删除失败");
		}
		return "redirect:/order/list";
	}
	
	@GetMapping("/input")
	public String input(Model model) {
		List<Seller> sellers = sellerService.getAllSeller();
		model.addAttribute("sellers", sellers);
		return "order/input";
	}
	
	@PostMapping("/save")
	public String save(Order order, RedirectAttributes redirectAttributes) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		log.info("订单信息：{}", order);
		try {
			if (null == order.getId()) { // 判断id是空
				order.setCreateTime(new Date());
				order.setCreateUid(user.getId());
				order.setCreateUname(user.getName());
				order.setState(1);
				order.setSellerName(sellerService.getSellerById(order.getSellerId()).getName());
				orderService.insertOrder(order);
			} else {
				orderService.updateOrder(order);
			}
			// 告诉页面添加成功
			redirectAttributes.addFlashAttribute("successMessage", "保存成功");
		} catch (Throwable e) {
			log.info("OrderController:save()--->{}", e.getMessage());
			// 告诉页面添加失败
			redirectAttributes.addFlashAttribute("errorMessage", "保存失败");
		}
		return "redirect:/order/list";
	}
	
	@RequestMapping(value = "/pagedlist", produces="application/json;charset=UTF-8")
	@ResponseBody
	public Map<String, Object> pagedlist(
			OrderVO orderVO,
			@RequestParam(value="page", required=false, defaultValue="1") int page, 
			@RequestParam(value="rows", required=false, defaultValue="10") int rows) {
		log.info("当前页是：{}，每一页{}条记录", page, rows);
		log.info("查询条件：{}", orderVO);
		OrderExample orderExample = new OrderExample();
		orderExample.setOrderByClause("id desc");
		Criteria createCriteria = orderExample.createCriteria();
		if (null != orderVO) {
			if (orderVO.getQOrderId() != null && !"".equals(orderVO.getQOrderId())) {
				createCriteria.andOrderIdLike("%" + orderVO.getQOrderId() + "%");
			}
			if (orderVO.getQMobile() != null && !"".equals(orderVO.getQMobile())) {
				createCriteria.andPhoneLike("%" + orderVO.getQMobile() + "%");
			}
			if (orderVO.getQSellerId() != null) {
				createCriteria.andSellerIdEqualTo(orderVO.getQSellerId());
			}
			if (orderVO.getQBegin() != null) {
				createCriteria.andCreateTimeGreaterThanOrEqualTo(orderVO.getQBegin());
			}
			if (orderVO.getQEnd() != null) {
				createCriteria.andCreateTimeLessThanOrEqualTo(new Date(orderVO.getQEnd().getTime() + (24 * 60 * 60 * 1000)));
			}
		}
		List<Order> orders = orderService.getOrdersPaged(orderExample, page, rows);
		PageInfo<Order> pageInfo = new PageInfo<>(orders);
		Map<String, Object> map = new HashMap<>();
		map.put("total", pageInfo.getTotal());
		map.put("rows", pageInfo.getList());
//		Gson gson = new GsonBuilder()
//		         .enableComplexMapKeySerialization()
//		         .serializeNulls()
//		         .setDateFormat("yyyy-MM-dd HH:mm:ss")
//		         .registerTypeAdapter(BigDecimal.class, new BigDecimalAdapter())
//		         .disableHtmlEscaping().create();
		return map;
	}
	
	@RequestMapping(value = "/pdpagedlist", produces="application/json;charset=UTF-8")
	@ResponseBody
	public Map<String, Object> pdpagedlist(
			OrderVO orderVO,
			@RequestParam(value="page", required=false, defaultValue="1") int page, 
			@RequestParam(value="rows", required=false, defaultValue="10") int rows) {
		log.info("当前页是：{}，每一页{}条记录", page, rows);
		log.info("查询条件：{}", orderVO);
		OrderExample orderExample = new OrderExample();
		orderExample.setOrderByClause("id desc");
		Criteria createCriteria = orderExample.createCriteria();
		createCriteria.andStateEqualTo(1);
		if (null != orderVO) {
			if (orderVO.getQOrderId() != null && !"".equals(orderVO.getQOrderId())) {
				createCriteria.andOrderIdLike("%" + orderVO.getQOrderId() + "%");
			}
			if (orderVO.getQMobile() != null && !"".equals(orderVO.getQMobile())) {
				createCriteria.andPhoneLike("%" + orderVO.getQMobile() + "%");
			}
			if (orderVO.getQSellerId() != null) {
				createCriteria.andSellerIdEqualTo(orderVO.getQSellerId());
			}
			if (orderVO.getQBegin() != null) {
				createCriteria.andCreateTimeGreaterThanOrEqualTo(orderVO.getQBegin());
			}
			if (orderVO.getQEnd() != null) {
				createCriteria.andCreateTimeLessThanOrEqualTo(new Date(orderVO.getQEnd().getTime() + (24 * 60 * 60 * 1000)));
			}
		}
		List<Order> orders = orderService.getOrdersPaged(orderExample, page, rows);
		PageInfo<Order> pageInfo = new PageInfo<>(orders);
		Map<String, Object> map = new HashMap<>();
		map.put("total", pageInfo.getTotal());
		map.put("rows", pageInfo.getList());
//		Gson gson = new GsonBuilder()
//		         .enableComplexMapKeySerialization()
//		         .serializeNulls()
//		         .setDateFormat("yyyy-MM-dd HH:mm:ss")
//		         .registerTypeAdapter(BigDecimal.class, new BigDecimalAdapter())
//		         .disableHtmlEscaping().create();
		return map;
	}
	
	@GetMapping("/excelout")
	@ResponseBody
	public void excelOut(HttpServletResponse response) {
		// 1.从数据库查出order list
		OrderExample example = new OrderExample();
		example.setOrderByClause("id desc");
		List<Order> orders = orderService.getAllOrder(example);
	
		// List<Order>  ----> List<OrderExcelOutModel>;
		
		String fileName = "订单导出Excel";
		try {
			// 2.将orderlist转换成Excel
			List<Object> outList = converter(orders);
			XSSFWorkbook xssfWorkbook = PoiUtil.createXSSFWorkbook("订单信息", OrderExcelOutModel.class, outList);
			// 3.将excel写到客户端
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
			ServletOutputStream outputStream = response.getOutputStream();
			xssfWorkbook.write(outputStream);
			outputStream.flush();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private List<Object> converter(List<Order> orders) {
		List<Object> outList = new LinkedList<>();
		for (Iterator<Order> it = orders.iterator(); it.hasNext();) {
			Order order = it.next();
			OrderExcelOutModel model = new OrderExcelOutModel();
			model.setId(order.getId());
			model.setName(order.getName());
			model.setOrderId(order.getOrderId());
			model.setPhone(order.getPhone());
			model.setPrice(order.getPrice().toString());
			model.setSellerName(order.getSellerName());
			outList.add(model);
		}
		return outList;
	}
	
	@GetMapping("/toexcelinpage")
	public String toExcelInPage(Model model) {
		List<Seller> sellers = sellerService.getAllSeller();
		model.addAttribute("sellers", sellers);
		return "order/excelin";
	}
	
	@PostMapping("/excelsave")
	public String excelSave(@RequestParam("excelFile") MultipartFile file, Long sellerId, RedirectAttributes redirectAttributes) {
		// 1.让客户端上传excel文件到服务器
				// Excel文件要
		// 2.解析excel文件，将excel文件内容List<OrderExcelInputModel>
		// 提升用户体验：要做数据校验，是否客户的Excel文件的数据是没有问题
		// 提升用户体验：如果客户的Excel数据有问题，应该想办法通过某种形式告诉客户Excel哪行哪列数据有问题
		// List<OrderExcelInputModel> --> List<Order>
		// 3.遍历List<Order>,将Order一个一下存到数据库里面
		log.info("excelFile:{}", file);
		log.info("sellerId:{}", sellerId);
		XSSFWorkbook book;
		try {
			book = new XSSFWorkbook(file.getInputStream());
			List<Object> excelList = PoiAnalyticalData.AnalyticPoiExcel(book, OrderExcelInputModel.class);
			List<Order> orders = new LinkedList<>();
			for (Object in : excelList) {
				OrderExcelInputModel model = (OrderExcelInputModel) in;
				Order order = convert(model, sellerId);
				orders.add(order);
			}
			orderService.saveOrders(orders);
			redirectAttributes.addFlashAttribute("successMessage", "Excel导入成功！");
			
		} catch (Throwable e) {
			redirectAttributes.addFlashAttribute("errorMessage", "Excel导入失败！");
		} 
		return "redirect:/order/list";
	}
	
	private Order convert(OrderExcelInputModel model, Long sellerId) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		Order order = new Order();
		order.setOrderId(model.getOrderId());
		order.setAddress(model.getAddress());
		order.setCarType(model.getCarType());
		order.setCreateTime(new Date());
		order.setCreateUid(user.getId());
		order.setCreateUname(user.getName());
		order.setProduct(model.getProduct());
		order.setRemark(model.getRemark());
		order.setName(model.getName());
		order.setPrice(new BigDecimal(model.getPrice()));
		order.setPhone(model.getPhone());
		order.setState(1);
		order.setSellerId(sellerId);
		order.setSellerName(sellerService.getSellerById(sellerId).getName());
		return order;
	}
	
	@GetMapping("/pdlist")
	public String pdlist(Model model) {
		List<Seller> sellers = sellerService.getAllSeller();
		model.addAttribute("sellers", sellers);
		return "order/pdlist";
	}
	
	@GetMapping("/pd/{id}")
	public String pd(@PathVariable Long id, Model model) {
		Order order = orderService.getOrderById(id);
		model.addAttribute("order", order);
		return "order/pd";
	}
	
	@PostMapping("/getregionsbyparid")
	@ResponseBody
	public List<Region> getRegionsByParId(@RequestParam("parId") Long parId) {
		return regionService.findByParId(parId);
	}
	
	@PostMapping("/pdsave")
	public String pdSave(Long id, Long storeId, RedirectAttributes redirectAttributes) {
		try {
			User user = (User) SecurityUtils.getSubject().getPrincipal();
			Order order = orderService.getOrderById(id);
			order.setStoreId(storeId);
			order.setStoreName(storeService.getStoreByPrimaryKey(storeId).getName());
			order.setState(2);
			order.setPdTime(new Date());
			order.setPdUid(user.getId());
			order.setPdUname(user.getName());
			orderService.pd(order);
			redirectAttributes.addFlashAttribute("successMessage", "派单成功！");
		} catch (Exception e) {
			log.info("OrderController.pdsave()--{}", e.getMessage());
			redirectAttributes.addFlashAttribute("successMessage", "派单失败！");
		}
		return "redirect:/order/pdlist";
	}
	
	@GetMapping("/hx")
	public String hx() {
		return "order/hx";
	}
	
	@PostMapping("/hx")
	public String hx(String hxm, Model model) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		Hxm h = hxmRandomService.getHxmByHxmstring(hxm);
		try {
			if (h == null) {
				// 核销码不正确
				model.addAttribute("errorMessage", "核销码不正确！");
			} else {
				Long orderId = h.getOrderId();
				Order order = orderService.getOrderById(orderId);
				order.setHxTime(new Date());
				order.setHxUid(user.getId());
				order.setHxUname(user.getName());
				order.setState(3);
				orderService.hx(order, h);
				StringBuffer sb = new StringBuffer();
				sb.append("车主：").append(order.getName())
				.append("，手机：").append(order.getPhone())
				.append("，车型：").append(order.getCarType())
				.append(", 安装产品：").append(order.getProduct())
				.append("， 备注：").append(order.getRemark());
				model.addAttribute("successMessage", "核销成功[" + sb.toString() + "]");
			}
		} catch (Exception e) {
			log.error("OrderController.hx(String,Hxm)-->{}", e.getMessage());
			model.addAttribute("errorMessage", "核销失败！");
		}
		return "order/hx";
	}
	
}
